from django.db import models
from django.contrib.auth.models import User


class VoiceCommand(models.Model):
    """语音命令模型"""
    COMMAND_TYPE_CHOICES = [
        ('device_control', '设备控制'),
        ('scene_execute', '场景执行'),
        ('query_status', '状态查询'),
        ('system_setting', '系统设置'),
        ('unknown', '未知命令'),
    ]
    
    LANGUAGE_CHOICES = [
        ('zh-cn', '中文'),
        ('en-us', '英文'),
    ]

    user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="用户")
    original_text = models.TextField(verbose_name="原始文本")
    processed_text = models.TextField(blank=True, verbose_name="处理后文本")
    command_type = models.CharField(max_length=20, choices=COMMAND_TYPE_CHOICES, verbose_name="命令类型")
    language = models.CharField(max_length=10, choices=LANGUAGE_CHOICES, default='zh-cn', verbose_name="语言")
    intent = models.CharField(max_length=100, blank=True, verbose_name="意图识别")
    entities = models.JSONField(default=dict, verbose_name="实体提取")
    confidence = models.FloatField(default=0.0, verbose_name="置信度")
    is_executed = models.BooleanField(default=False, verbose_name="是否已执行")
    execution_result = models.JSONField(default=dict, verbose_name="执行结果")
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")

    class Meta:
        verbose_name = "语音命令"
        verbose_name_plural = "语音命令"
        ordering = ['-created_at']

    def __str__(self):
        return f"{self.user.username} - {self.original_text[:50]}..."

    @property
    def is_high_confidence(self):
        """检查是否为高置信度命令"""
        return self.confidence >= 0.8

    def get_target_device(self):
        """获取目标设备"""
        if 'device' in self.entities:
            return self.entities['device']
        return None

    def get_action(self):
        """获取动作"""
        if 'action' in self.entities:
            return self.entities['action']
        return None


class CommandTemplate(models.Model):
    """命令模板模型"""
    name = models.CharField(max_length=100, verbose_name="模板名称")
    pattern = models.TextField(verbose_name="匹配模式")
    intent = models.CharField(max_length=100, verbose_name="意图")
    command_type = models.CharField(max_length=20, choices=VoiceCommand.COMMAND_TYPE_CHOICES, verbose_name="命令类型")
    entity_mapping = models.JSONField(default=dict, verbose_name="实体映射")
    response_template = models.TextField(blank=True, verbose_name="响应模板")
    is_active = models.BooleanField(default=True, verbose_name="是否启用")
    priority = models.IntegerField(default=0, verbose_name="优先级")
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")

    class Meta:
        verbose_name = "命令模板"
        verbose_name_plural = "命令模板"
        ordering = ['-priority', 'name']

    def __str__(self):
        return self.name

    def match_text(self, text):
        """匹配文本"""
        import re
        pattern = self.pattern.replace('{device}', r'(?P<device>\w+)').replace('{action}', r'(?P<action>\w+)')
        match = re.search(pattern, text, re.IGNORECASE)
        return match

    def extract_entities(self, text):
        """提取实体"""
        match = self.match_text(text)
        if match:
            entities = match.groupdict()
            # 应用实体映射
            for key, mapping in self.entity_mapping.items():
                if key in entities and entities[key] in mapping:
                    entities[key] = mapping[entities[key]]
            return entities
        return {}


class NLPProcessingLog(models.Model):
    """NLP处理日志模型"""
    PROCESSING_STATUS_CHOICES = [
        ('success', '成功'),
        ('failed', '失败'),
        ('partial', '部分成功'),
    ]

    voice_command = models.ForeignKey(VoiceCommand, on_delete=models.CASCADE, verbose_name="语音命令")
    processing_step = models.CharField(max_length=50, verbose_name="处理步骤")
    status = models.CharField(max_length=20, choices=PROCESSING_STATUS_CHOICES, verbose_name="处理状态")
    input_data = models.JSONField(default=dict, verbose_name="输入数据")
    output_data = models.JSONField(default=dict, verbose_name="输出数据")
    error_message = models.TextField(blank=True, verbose_name="错误信息")
    processing_time = models.FloatField(default=0.0, verbose_name="处理时间(秒)")
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")

    class Meta:
        verbose_name = "NLP处理日志"
        verbose_name_plural = "NLP处理日志"
        ordering = ['-created_at']

    def __str__(self):
        return f"{self.voice_command.id} - {self.processing_step} ({self.get_status_display()})"


class DeviceAlias(models.Model):
    """设备别名模型"""
    device = models.ForeignKey('devices.Device', on_delete=models.CASCADE, verbose_name="设备")
    alias = models.CharField(max_length=100, verbose_name="别名")
    language = models.CharField(max_length=10, choices=VoiceCommand.LANGUAGE_CHOICES, default='zh-cn', verbose_name="语言")
    is_active = models.BooleanField(default=True, verbose_name="是否启用")
    created_by = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="创建者")
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")

    class Meta:
        verbose_name = "设备别名"
        verbose_name_plural = "设备别名"
        unique_together = ['device', 'alias', 'language']

    def __str__(self):
        return f"{self.device.name} - {self.alias}"


class ActionAlias(models.Model):
    """动作别名模型"""
    ACTION_CHOICES = [
        ('turn_on', '开启'),
        ('turn_off', '关闭'),
        ('set_temperature', '设置温度'),
        ('set_brightness', '设置亮度'),
        ('set_volume', '设置音量'),
        ('play', '播放'),
        ('pause', '暂停'),
        ('stop', '停止'),
        ('increase', '增加'),
        ('decrease', '减少'),
    ]

    action = models.CharField(max_length=50, choices=ACTION_CHOICES, verbose_name="动作")
    alias = models.CharField(max_length=100, verbose_name="别名")
    language = models.CharField(max_length=10, choices=VoiceCommand.LANGUAGE_CHOICES, default='zh-cn', verbose_name="语言")
    device_type = models.ForeignKey('devices.DeviceType', on_delete=models.CASCADE, blank=True, null=True, verbose_name="适用设备类型")
    is_active = models.BooleanField(default=True, verbose_name="是否启用")
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")

    class Meta:
        verbose_name = "动作别名"
        verbose_name_plural = "动作别名"
        unique_together = ['action', 'alias', 'language']

    def __str__(self):
        return f"{self.get_action_display()} - {self.alias}"


class ConversationContext(models.Model):
    """对话上下文模型"""
    user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="用户")
    session_id = models.CharField(max_length=100, verbose_name="会话ID")
    context_data = models.JSONField(default=dict, verbose_name="上下文数据")
    last_intent = models.CharField(max_length=100, blank=True, verbose_name="最后意图")
    last_entities = models.JSONField(default=dict, verbose_name="最后实体")
    conversation_state = models.CharField(max_length=50, default='idle', verbose_name="对话状态")
    expires_at = models.DateTimeField(verbose_name="过期时间")
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")

    class Meta:
        verbose_name = "对话上下文"
        verbose_name_plural = "对话上下文"
        unique_together = ['user', 'session_id']

    def __str__(self):
        return f"{self.user.username} - {self.session_id}"

    def is_expired(self):
        """检查上下文是否过期"""
        from django.utils import timezone
        return timezone.now() > self.expires_at

    def extend_expiry(self, minutes=30):
        """延长过期时间"""
        from django.utils import timezone
        from datetime import timedelta
        self.expires_at = timezone.now() + timedelta(minutes=minutes)
        self.save(update_fields=['expires_at', 'updated_at'])
